﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using System.IO;
using System.Data.SqlClient;
using System.Configuration;

namespace RecycleBinRestoreApp
{
    
    public partial class Form1 : Form
    {
        protected String WebId { get; set; }
        protected String SiteId { get; set; }
        protected String DirName { get; set; }
        protected String ListDirName { get; set; }
        protected String ListId { get; set; }
        protected String ListRootParentId { get; set; }

        public Form1()
        {
            InitializeComponent();
        }

        protected void ReloadItems()
        {
            try
            {
                using (SPSite site = new SPSite(this.textBox1.Text))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        this.checkedListBox1.Items.Clear();
                        this.comboBox1.Items.Clear();
                        for (int x = 0; x < web.RecycleBin.Count; ++x)
                        {
                            this.checkedListBox1.Items.Add("Title: " + web.RecycleBin[x].Title + " | Directory Name: " + web.RecycleBin[x].DirName + " | Item State: " + web.RecycleBin[x].ItemState);
                        }
                        foreach (SPList list in web.Lists)
                        {
                            this.comboBox1.Items.Add(list.Title);
                        }
                        this.SiteId = site.ID.ToString();
                        this.WebId = web.ID.ToString();
                    }
                }
            }
            catch (Exception ex)
            {
                this.textBox2.Text += ex.Message + " #######\n" + ex.StackTrace;
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            String connectionString = ConfigurationSettings.AppSettings["DBConnectionString"];
            SqlDataReader rdr = null;
            this.textBox2.Text += "Opening connection to DB";
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                this.textBox2.Text += "Connection opened";
                List<RecycleBinDBItem> items = new List<RecycleBinDBItem>();
                try
                {
                    SqlCommand cmd = new SqlCommand("SELECT * FROM RecycleBin WHERE ListDirName IS NULL", connection);

                 rdr = cmd.ExecuteReader();
                 this.textBox2.Text += "Select clause executed";
                     while (rdr.Read())
                     {
                         this.textBox2.Text += "Reading line: \n";
                         this.textBox2.Text += rdr["DirName"].ToString();
                         items.Add(new RecycleBinDBItem(rdr["DirName"].ToString(), rdr["WebId"].ToString(), rdr["SiteId"].ToString(), rdr["DocId"].ToString()));
                     }
                 }
                 finally
                 {
                     // close the reader
                     if (rdr != null)
                     {
                         rdr.Close();
                     }
                     int itemIDCounter = 5000;
                     int authorID = 1;
                     foreach (RecycleBinDBItem item in items)
                     {
                         try
                         {
                             ++itemIDCounter;
                             using (SPSite site = new SPSite(new Guid(item.siteID)))
                             {
                                 using (SPWeb web = site.OpenWeb(new Guid(item.webID)))
                                 {
                                     SPList list = web.GetList("/" + item.dirName);
                                     string updateString = String.Format("update RecycleBin set ListID = '{0}', ListItemId = {1}, AuthorId= {2},ListDirName = '{3}' where DocId = '{4}'",
                                                                            list.ID, itemIDCounter, authorID, list.RootFolder.ServerRelativeUrl.Remove(0, 1), item.docID);

                                     using (SqlCommand updateCmd = new SqlCommand(updateString))
                                     {
                                         updateCmd.Connection = connection;
                                         updateCmd.ExecuteNonQuery();
                                     }
                                     this.textBox2.Text += "Update executed for item: " + item.dirName + "\n";
                                 }
                             }
                         }
                         catch (SqlException sqlex)
                         {
                             this.textBox2.Text += sqlex.Message + " #######\n" + sqlex.StackTrace;
                         }
                         catch (Exception ex)
                         {
                             this.textBox2.Text += ex.Message + " #######\n" + ex.StackTrace;
                         }
                     }
                 } 
            }
            this.textBox2.Text += "DB operations done!";
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            this.ReloadItems();
            this.checkedListBox1.Enabled = true;
            this.comboBox1.Enabled = true;
            this.button2.Enabled = true;
            this.button3.Enabled = true;
            this.button4.Enabled = true;
            this.button5.Enabled = true;
            this.button6.Enabled = true;
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            try
            {
                using (SPSite site = new SPSite(this.textBox1.Text))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        List<Guid> guids = new List<Guid>();
                        for (int y = 0; y < this.checkedListBox1.CheckedItems.Count; ++y)
                        {
                            guids.Add(web.RecycleBin[y].ID);
                        }
                        web.RecycleBin.Restore(guids.ToArray());
                    }
                }
                this.ReloadItems();
            }
            catch (Exception ex)
            {
                this.textBox2.Text += ex.Message + " #######\n" + ex.StackTrace;
            }
        }

        private void button3_Click_1(object sender, EventArgs e)
        {
            try
            {
                using (SPSite site = new SPSite(this.textBox1.Text))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        List<Guid> guids = new List<Guid>();
                        for (int y = 0; y < this.checkedListBox1.CheckedItems.Count; ++y)
                        {
                            guids.Add(web.RecycleBin[y].ID);
                        }
                        web.RecycleBin.Delete(guids.ToArray());
                    }
                }
                this.ReloadItems();
            }
            catch (Exception ex)
            {
                this.textBox2.Text += ex.Message + " #######\n" + ex.StackTrace;
            }
        }

        private void button4_Click_1(object sender, EventArgs e)
        {
            try
            {
                using (SPSite site = new SPSite(this.textBox1.Text))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        List<Guid> guids = new List<Guid>();
                        for (int y = 0; y < this.checkedListBox1.CheckedItems.Count; ++y)
                        {
                            if (web.RecycleBin[y].ItemState == SPRecycleBinItemState.FirstStageRecycleBin)
                                guids.Add(web.RecycleBin[y].ID);
                        }
                        web.RecycleBin.MoveToSecondStage(guids.ToArray());
                    }
                }
                this.ReloadItems();
            }
            catch (Exception ex)
            {
                this.textBox2.Text += ex.Message + " #######\n" + ex.StackTrace;
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                String connectionString = ConfigurationSettings.AppSettings["DBConnectionString"];
                SqlDataReader rdr = null;
                this.textBox2.Text += "Opening connection to DB";
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    connection.Open();
                    this.textBox2.Text += "Connection opened";
                    List<RecycleBinDBItem> items = new List<RecycleBinDBItem>();
                    try
                    {
                        SqlCommand cmd = new SqlCommand("SELECT DocId FROM RecycleBin WHERE ListDirName IS NULL", connection);

                        rdr = cmd.ExecuteReader();
                        this.textBox2.Text += "Select clause executed";

                        while (rdr.Read())
                        {
                            this.textBox2.Text += "Reading line: \n";
                            this.textBox2.Text += rdr["DocId"].ToString();
                            items.Add(new RecycleBinDBItem(this.DirName, this.WebId, this.SiteId, rdr["DocId"].ToString(), this.ListDirName, this.ListId, this.ListRootParentId));
                        }
                    }
                    finally
                    {
                        // close the reader
                        if (rdr != null)
                        {
                            rdr.Close();
                        }
                        int itemIDCounter = 5000;
                        int authorID = 1;
                        foreach (RecycleBinDBItem item in items)
                        {
                            try
                            {
                                ++itemIDCounter;
                                using (SPSite site = new SPSite(new Guid(item.siteID)))
                                {
                                    using (SPWeb web = site.OpenWeb(new Guid(item.webID)))
                                    {
                                        string updateString = String.Format("update RecycleBin set ListID = '{0}', ListItemId = {1}, AuthorId= {2},ListDirName = '{3}', DirName = '{4}', WebId = '{5}', SiteId = '{6}' where DocId = '{7}'",
                                                                               item.listId, itemIDCounter, authorID, this.ListDirName, this.DirName, this.WebId, this.SiteId, item.docID);

                                        using (SqlCommand updateCmd = new SqlCommand(updateString))
                                        {
                                            updateCmd.Connection = connection;
                                            updateCmd.ExecuteNonQuery();
                                        }

                                        updateString = String.Format("update AllDocs set ListID = '{0}', DirName = '{1}', WebId = '{2}', SiteId = '{3}', ParentId = '{4}' where Id = '{5}'",
                                                                               item.listId, this.DirName, this.WebId, this.SiteId, this.ListRootParentId, item.docID);

                                        using (SqlCommand updateCmd = new SqlCommand(updateString))
                                        {
                                            updateCmd.Connection = connection;

                                            updateCmd.ExecuteNonQuery();
                                        }

                                        updateString = String.Format("update AllDocStreams set ParentId = '{0}' where Id = '{1}'",
                                                                               item.rootFolderParentId, item.docID);

                                        using (SqlCommand updateCmd = new SqlCommand(updateString))
                                        {
                                            updateCmd.Connection = connection;

                                            updateCmd.ExecuteNonQuery();
                                        }
                                        this.textBox2.Text += "Update executed for item: " + item.dirName + "\n";
                                    }
                                }
                            }
                            catch (SqlException sqlex)
                            {
                                this.textBox2.Text += sqlex.Message + " #######\n" + sqlex.StackTrace;
                            }
                            catch (Exception ex)
                            {
                                this.textBox2.Text += ex.Message + " #######\n" + ex.StackTrace;
                            }
                        }
                    }
                }
                this.textBox2.Text += "DB operations done!";
            }
            catch (Exception ex)
            {
                this.textBox2.Text += ex.Message + " #######\n" + ex.StackTrace;
            }
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                using (SPSite site = new SPSite(new Guid(this.SiteId)))
                {
                    using (SPWeb web = site.OpenWeb(new Guid(WebId)))
                    {
                        String listName = this.comboBox1.SelectedItem as String;
                        if(!String.IsNullOrEmpty(listName))
                        {
                            SPList list = web.Lists[listName];
                            if (list != null)
                            {
                                this.ListDirName = list.RootFolder.ServerRelativeUrl.Remove(0, 1);
                                this.DirName = list.RootFolder.ServerRelativeUrl.Remove(0, 1);
                                this.ListId = list.ID.ToString();
                                this.ListRootParentId = list.RootFolder.UniqueId.ToString();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.textBox2.Text += ex.Message + " #######\n" + ex.StackTrace;
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {

            String connectionString = ConfigurationSettings.AppSettings["DBConnectionString"];
            SqlDataReader rdr = null;
            this.textBox2.Text += "Opening connection to DB";
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                this.textBox2.Text += "Connection opened";
                List<RecycleBinDBItem> items = new List<RecycleBinDBItem>();
                try
                {
                    // Get all such items which can not be restored properly from the UI or by object model
                    SqlCommand cmd = new SqlCommand("SELECT * FROM RecycleBin WHERE ListDirName IS NULL", connection);

                    rdr = cmd.ExecuteReader();
                    this.textBox2.Text += "Select clause executed";

                    while (rdr.Read())
                    {
                        this.textBox2.Text += "Reading line: \n";
                        this.textBox2.Text += rdr["DirName"].ToString();
                        items.Add(new RecycleBinDBItem(rdr["DocId"].ToString(), rdr["LeafName"].ToString()));
                    }
                }
                finally
                {
                    // close the reader
                    if (rdr != null)
                    {
                        rdr.Close();
                    }
                    int itemIDCounter = 5000;
                    int authorID = 1;
                    // Loop through every recycle bin items that is missing needed field data from the RecycleBin table to be restored properly
                    foreach (RecycleBinDBItem item in items)
                    {
                        try
                        {
                            SqlCommand cmd = new SqlCommand(String.Format("SELECT Content FROM AllDocStreams WHERE Id = '{0}'", item.docID ), connection);

                            // 2. Call Execute reader to get query results
                            byte [] bArray = (byte[])cmd.ExecuteScalar();
                            // Craete the file and write the binary data from the Database
                            FileStream fs = File.Create(item.fileName, (int)bArray.Length);
                            fs.Write(bArray, 0, bArray.Length);
                            fs.Flush();
                            fs.Close();
                        }
                        catch (SqlException sqlex)
                        {
                            this.textBox2.Text += sqlex.Message + " #######\n" + sqlex.StackTrace;
                        }
                        catch (Exception ex)
                        {
                            this.textBox2.Text += ex.Message + " #######\n" + ex.StackTrace;
                        }
                        finally
                        {
                            if (rdr != null)
                            {
                                rdr.Close();
                            }
                        }
                    }
                }
            }
            this.textBox2.Text += "DB operations done!";
        }
    }
}
